﻿using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;
using static System.Net.Mime.MediaTypeNames;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceTrafficInfo")]
	public class ConferenceTrafficInfoController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceTrafficInfo;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceTrafficInfoModel();
			model.ConferenceId = conferenceId;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceTrafficInfoModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = from profileTrafficInfo in DbContext.ProfileTrafficInfo.AsNoTracking().Where(x => x.ConferenceId == model.ConferenceId)
				  join trafficMaster in DbContext.TrafficMaster.AsNoTracking()
					.Where(x => x.ConferenceId == model.ConferenceId && x.Status == ConstValues.Status.正常)
					  on profileTrafficInfo.TrafficId equals trafficMaster.ID
				  select new
				  {
					  Id = profileTrafficInfo.ID,
					  Status = profileTrafficInfo.Status,
					  OrderNum = profileTrafficInfo.OrderNum,
					  TrafficId = profileTrafficInfo.TrafficId,
					  TrafficName = trafficMaster.TrafficName,
					  TrafficType = profileTrafficInfo.TrafficType,
					  FullName = profileTrafficInfo.FullName,
					  Mobile = profileTrafficInfo.Mobile,
					  Mail = profileTrafficInfo.Mail,
					  Fee = profileTrafficInfo.Fee,
					  Currency = profileTrafficInfo.Currency,
					  Remark = profileTrafficInfo.Remark
				  };

			if (!string.IsNullOrEmpty(model.SelNameMobileMail))
			{
				sql = sql.Where(x => x.FullName.Contains(model.SelNameMobileMail) ||
						x.Mobile.Contains(model.SelNameMobileMail) ||
						x.Mail.Contains(model.SelNameMobileMail));
			}

			if (!string.IsNullOrEmpty(model.SelTraffic))
			{
				sql = sql.Where(x => x.TrafficId == model.SelTraffic);
			}

			if (!string.IsNullOrEmpty(model.SelTrafficType))
			{
				sql = sql.Where(x => x.TrafficType == model.SelTrafficType);
			}

			if (!string.IsNullOrEmpty(model.SelStatus))
			{
				sql = sql.Where(x => x.Status == model.SelStatus);
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.OrderNum).ThenBy(x => x.TrafficName).ThenBy(x => x.TrafficType).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.Id,
				Status = x.Status,
				OrderNum = x.OrderNum,
				TrafficName = x.TrafficName,
				TrafficType = Utility.ChangeTrafficTypeToResources(x.TrafficType),
				FullName = x.FullName,
				Mobile = x.Mobile,
				Mail = x.Mail,
				Fee = x.Fee.ToString("N2"),
				Currency = x.Currency,
				Remark = x.Remark
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<FileResult> Export(string allId,string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var ids = allId.Split(ConstValues.chrComma);
			var sql = from profileTrafficInfo in DbContext.ProfileTrafficInfo.AsNoTracking().Where(x => ids.Contains(x.ID.ToString()))
				  join trafficMaster in DbContext.TrafficMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
					  on profileTrafficInfo.TrafficId equals trafficMaster.ID
				  orderby profileTrafficInfo.OrderNum, trafficMaster.TrafficName, trafficMaster.TrafficType
				  select new
				  {
					  Id = profileTrafficInfo.ID,
					  Status = profileTrafficInfo.Status,
					  OrderNum = profileTrafficInfo.OrderNum,
					  TrafficId = profileTrafficInfo.TrafficId,
					  TrafficName = trafficMaster.TrafficName,
					  TrafficType = Utility.ChangeTrafficTypeToResources(trafficMaster.TrafficType),
					  FullName = profileTrafficInfo.FullName,
					  Mobile = profileTrafficInfo.Mobile,
					  Mail = profileTrafficInfo.Mail,
					  Fee = profileTrafficInfo.Fee,
					  Currency = profileTrafficInfo.Currency,
					  Remark = profileTrafficInfo.Remark
				  };

			var result = await sql.ToListAsync();

			var export = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
					Resources.export_trafficInfoCN : Resources.export_trafficInfoEN;

			XSSFWorkbook workbook;

			using (MemoryStream readStream = new MemoryStream(export))
			{
				workbook = new XSSFWorkbook(readStream);
				ISheet sheet = workbook.GetSheetAt(0);

				var count = 0;
				foreach (var model in result)
				{
					count += 1;
					IRow row = sheet.CreateRow(count);

					// 订单号
					int column = 0;
					ICell cell = row.CreateCell(column);
					cell.SetCellValue(model.OrderNum);

					// 接送方式
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.TrafficName);

					// 服务类型
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.TrafficType);

					// 姓名
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.FullName);

					// 手机
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.Mobile);

					// 邮箱
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.Mail);

					// 价格
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.Fee.ToString("N2"));

					// 币种
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.Currency);

					// 备注
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(model.Remark);
				}
			}

			MemoryStream exportStream = new MemoryStream();
			workbook.Write(exportStream);
			exportStream.Flush();
			exportStream.Position = 0;

			return File(exportStream, Application.Octet,
					$"export_trafficInfo_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx");
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("SetBooking/{ConferenceId}")]
		public async Task<JsonResult> SetBooking(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);
			
			var result = await DbContext.ProfileTrafficInfo
					.FirstOrDefaultAsync(x => x.ID == model.ProfileTrafficId);

			if (result != null)
			{
				result.Status = ConstValues.Status.已预订;
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessBooking),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("EditTraffic/{ConferenceId}")]
		public async Task<JsonResult> EditTraffic(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var trafficList = model.TrafficList;
			var isTrue = true;
			var orderNum = model.OrderNumber;

			trafficList.ForEach(x =>
			{
				var profileTrafficInfo = DbContext.ProfileTrafficInfo.FirstOrDefault(y => y.ID == model.ProfileTrafficId);
				var trafficMaster = DbContext.TrafficMaster.FirstOrDefault(y => y.ID == x.TrafficId);
				if (profileTrafficInfo != null && trafficMaster != null)
				{
					profileTrafficInfo.FlightDate = Convert.ToDateTime(x.FlightDate);
					profileTrafficInfo.FlightNum = x.FlightNum.Trim();
					profileTrafficInfo.TrafficId = x.TrafficId;
					profileTrafficInfo.FullName = x.ContactName.Trim();
					profileTrafficInfo.Mail = x.ContactMail.Trim();
					profileTrafficInfo.Mobile = x.ContactMobile.Trim();
					profileTrafficInfo.Remark = string.IsNullOrEmpty(x.Remark) ? string.Empty : x.Remark.Trim();
					profileTrafficInfo.Currency = trafficMaster.Currency;
					profileTrafficInfo.Fee = trafficMaster.Price.Value;
				}
				else
				{
					isTrue = false;
				}
			});
			await DbContext.SaveChangesAsync();

			if (isTrue)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}
		
		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("CancelBooking/{ConferenceId}")]
		public async Task<JsonResult> CancelBooking(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ProfileTrafficInfo
					.FirstOrDefaultAsync(x => x.ID == model.ProfileTrafficId);

			if (result != null)
			{
				result.Status = ConstValues.Status.已取消;
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessCancel),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}
	}
}